package com.pignest.hotel.ui.income;

import java.util.Date;

import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Textbox;

import com.pignest.framework.util.Utils;
import com.pignest.hotel.beans.Living;
import com.pignest.hotel.beans.Member;
import com.pignest.hotel.beans.Memberchargehistrory;
import com.pignest.hotel.beans.TbAccounts;
import com.pignest.hotel.beans.TbCloseAccounts;
import com.pignest.hotel.beans.User;
import com.pignest.hotel.definition.ChargeOpType;
import com.pignest.hotel.definition.InComeItemType;
import com.pignest.hotel.definition.OpenRoomType;
import com.pignest.hotel.definition.PayMethod;
import com.pignest.hotel.service.IncomeService;
import com.pignest.hotel.service.MemberService;
import com.pignest.hotel.spring.Services;
import com.pignest.hotel.system.Global;
import com.pignest.hotel.system.Hotel;
import com.pignest.hotel.system.InComeUtil;
import com.pignest.hotel.system.Logic;
import com.pignest.hotel.util.DateUtil;
import com.pignest.hotel.util.UIUtils;

public class InComeCheckOutWindow extends BaseCheckOutWindow {

	private static final long serialVersionUID = -4814269696660851520L;
	private IncomeService incomeService;
	private MemberService memberService;
	/***合计项***/
	private Label aStorage;
	private Label aUsed;
	private Label aPayed;
	private Label aAvailable;
	private Label aLivingTime;
	private Label aLeavingTime;
	private Textbox aAddPay;//所有加收金额
	
	private Label roomType;
	private Label openType;
	
	private Textbox roomName;
	private Label storage;
	private Label used;
	private Label payed;
	private Label available;//当前余额
	private Textbox singleaddPay;//当前加收情况
	private Textbox adjustPrice;
	//private Textbox accounts;//结账金额
	
	private Listbox selectLivingList;//选择结账人与房间
   // private Listbox targetselectLivingList;//要结账的目标列表
   // private Grid targetGrid;
    private Listbox addPayList;
	private Listbox paymentMethod;//结账类型
	private Listbox invoiceListbox;//是否开票

	private Textbox mCardNumber;//会员卡号
	
	private Textbox livingTime;//到达时间
	private Textbox leaveTime;//离开时间
	
	private Button okBtn;
	private Label opTip;
	private Grid memberGrid;
	private Date earlyTime;
	private Date checkTime;
	
	private Living curLiving;
	
	public InComeCheckOutWindow() {
		incomeService =Services.getIncomeService();
		memberService=Services.getMemberService();
		addEventListener("onCreate", this);
	}
	
	@Override
	protected void onCreate() {
			aStorage = (Label) getFellow("aStorage");
			aUsed = (Label) getFellow("aUsed");
			aPayed = (Label) getFellow("aPayed");
			aAvailable = (Label) getFellow("aAvailable");
			aLivingTime = (Label) getFellow("aLivingTime");
			aLeavingTime = (Label) getFellow("aLeavingTime");
			aAddPay = (Textbox) getFellow("aAddPay");
			roomName = (Textbox) getFellow("roomName");
			storage = (Label) getFellow("storage");
			used = (Label) getFellow("used");
			payed = (Label) getFellow("payed");
			livingTime = (Textbox) getFellow("livingTime");
			leaveTime = (Textbox) getFellow("leaveTime");
			available = (Label) getFellow("available");
			singleaddPay = (Textbox) getFellow("singleaddPay");
			adjustPrice = (Textbox) getFellow("adjustPrice");

			roomType = (Label) getFellow("roomType");
			openType = (Label) getFellow("openType");
	
			paymentMethod=(Listbox)getFellow("paymentMethod");
			invoiceListbox=(Listbox)getFellow("invoiceListbox");
			selectLivingList=(Listbox)getFellow("selectLivingList");
			//targetselectLivingList=(Listbox)getFellow("targetselectLivingList");
			addPayList=(Listbox)getFellow("addPayList");
			mCardNumber=(Textbox)getFellow("mCardNumber");
			
			opTip=(Label)getFellow("opTip");
			okBtn=(Button)getFellow("okBtn");
			memberGrid=(Grid)getFellow("memberGrid");
			//targetGrid=(Grid)getFellow("targetGrid");
			memberGrid.setVisible(false);
			selectLivingList.addEventListener(Events.ON_SELECT, new EventListener(){
				   public void onEvent(Event event) {
					   //initSelectLiving();
					   //selectSingleAddPay();
					   initMoney();
				   }
			   });
			addPayList.addEventListener(Events.ON_SELECT, new EventListener(){
				   public void onEvent(Event event) {
					  // selectSingleAddPay();
					   initMoney();
				   }
			   });
			paymentMethod.addEventListener(Events.ON_SELECT, new EventListener(){
				   public void onEvent(Event event) {
					   //PayMethod payMethod=UIUtils.getSelectedValue(paymentMethod);
					   String sPayMetod =UIUtils.getSelectedValue(paymentMethod);
					   if(sPayMetod.equals(PayMethod.MEMBER_CARD.name()))
					   {
						   memberGrid.setVisible(true);
						  // targetGrid.setVisible(false);
					   }else{
						   memberGrid.setVisible(false);
						  // targetGrid.setVisible(true);
						   okBtn.setDisabled(false);
					   }
					   
				   }
			   });
			init();
	}
	public void init()
	{
		//1、初始化所有账户信息、同时选择最早的记录，初始化第一条信息
		initAllLiviingListbox();
		//2、初始化加收情况:根据最早入住、与当前时间，默认选中加收的信息
		initAddPay();//
		//3、初始化总额，其中总余额=总存入-总消费－加收费用
		initMoney();
	}
	//1
	public void initAllLiviingListbox()
	{
		if(selectLive==null || selectLive.isEmpty()) {
			UIUtils.alert("无效的入住!请选择入住记录");
			this.detach();
		}
		selectLive =incomeService.queryBySelf(selectLive);
		this.setTitle("共选择了"+selectLive.size()+"记录");
		selectLivingList.getItems().clear();
		int i=0;
		for(Living l:selectLive) {
			Listitem listitem = new Listitem();
			listitem.setParent(selectLivingList);
			listitem.setValue(l);
			if(i==0){
		         setEarlyTime(l.getLiveTime());//必须先
		         setCheckTime(new Date());
			     aLivingTime.setValue(DateUtil.toString(l.getLiveTime(), DateUtil.HOTEL_DEFAULT_FORMAT));
			     aLeavingTime.setValue(DateUtil.toString(checkTime, DateUtil.HOTEL_DEFAULT_FORMAT));
				 listitem.setSelected(true);
			}
			if(l.getMember()!=null){
				UIUtils.setSelectedItem(paymentMethod, PayMethod.MEMBER_CARD.name());
				memberGrid.setVisible(true);
			}
			listitem.setLabel("["+l.getRoom().getName()+"]"+l.getCustormName());
			i++;
		}
	}
	//2初始化加收情况
	public void initAddPay()
	{
		int add=Logic.getLivingAdditionalTime(this.getEarlyTime(),this.getCheckTime(),true);
		UIUtils.setSelectedItem(addPayList,String.valueOf(add));
	}
	//3初始化各金额
	public void initMoney()
	{
		selectLive =incomeService.queryBySelf(selectLive);
		String v =UIUtils.getSelectedValue(addPayList);
		int add =Integer.valueOf(v);
		InComeUtil.countInComeAll(selectLive, aStorage, aUsed, aPayed, aAvailable, aAddPay, add);
		//个人账户
		Living sL =(Living)UIUtils.getSelectedValue(selectLivingList);
		//不变的
		roomName.setValue(sL.getRoom().getName());
		roomType.setValue(sL.getRoom().getType().getName());
		openType.setValue(OpenRoomType.valueOf(sL.getOpenRoomType()).getDisplayName());
		adjustPrice.setValue(Utils.toPrice(sL.getAdjustPrice()));
		livingTime.setValue(DateUtil.toString(sL.getLiveTime(), DateUtil.HOTEL_DEFAULT_FORMAT));
		leaveTime.setValue(DateUtil.toString(checkTime,DateUtil.HOTEL_DEFAULT_FORMAT));
		//变动的
		InComeUtil.countInComeSingle(sL, storage, used, payed, available, singleaddPay, add);
	}

	/**
	 * 1、当前所有结账是否有被结过
	 * 是  return ;
	 * 2、判断是否有借用未归还的物品
	 * 是，提供那个房间有未归还信息
	 * 3是否会员结账
	 *   3.1 是
	 *       判断该会员是否有可余额可结
	 *       是：
	 *         
	 *       否  请充值或者用现金结账 return 
	 *   3.2 否 
	 * 如果是多条记录一起结账则在Living生成同一serialNumber
	 * 如果有加收则在各自账户生成一条已结账加收记录   
	 * 在主结账户，close_account生成一条结账记录  
	 * 将所有消费项目的结账状态、结账时间设置成"结账"、结账时间，
	 * 如果是会员结账则生成
	 *   会员消费记录，并更新会员总额
	 * 4
	 * 
	 * **/
	
	public void checkOut()
	{
		if(!Hotel.onDuty()){
			UIUtils.alert("对不起你还未值班,不能操作此业务 !");
			return ;
		}
		if(!incomeService.isCheckedOut(selectLive)){
			return ;
		}
		if(!InComeUtil.isNoBorrow(selectLive)){
			return ;
		}
		StringBuffer msg = new StringBuffer();
		StringBuffer rMsg = new StringBuffer();
		StringBuffer finalAlert =new StringBuffer();
//		   finalAlert.append("谢谢你的光临");
		rMsg.append(InComeUtil.getAutoLivingReMark(selectLive,true));
		Living cur =(Living)UIUtils.getSelectedValue(selectLivingList);
		Living nCur=incomeService.get(Living.class, cur.getId());//防止长期没结而被其它人结了
		   msg.append("您好:").append(nCur.getCustormName()).append("\n");
		String rUnion="";
		String orderNo=DateUtil.toString(this.earlyTime, "yyyyMMddHHmmss");
		String serialNumber="";
		String checkOutNo="";
		int iUnion=selectLive.size();
		if(iUnion>1){
			rUnion="联房";
			serialNumber=Global.getLivineSerialNumber();
			msg.append("结账种类：联房").append("\n");
			msg.append("房间:\n").append(rMsg.toString()).append("\n");
		}else{
			rUnion="单人";
			msg.append("结账种类:单人").append("\n");
			msg.append("房间：").append(rMsg.toString()).append("\n");
		}
		
		String sPayMethod=UIUtils.getSelectedValue(paymentMethod);
		   msg.append("结账方式：").append(PayMethod.valueOf(sPayMethod).getDisplayName()).append("\n");
		//int storage=incomeService.querySavings(selectLive);//总存款
		int storage =incomeService.countAllStorages(selectLive, false);
		int comsum=incomeService.countCurCumsums(selectLive);//除加收外的消费
		String sAddpay =aAddPay.getValue();
		TbAccounts ac =null;
	   // int iAddpay =Utils.toPrice(sAddpay);
	    int centAddPay =Utils.toPrice(sAddpay);
		if(centAddPay!=0){
			String sAddPayName =(String)UIUtils.getSelectedLable(addPayList);
			int addDays =Integer.valueOf((String)UIUtils.getSelectedValue(addPayList));
			float addCount =addDays/2.0f*iUnion;
			  msg.append("加收：").append(sAddPayName).append("\n");
			  msg.append("加收金额:").append(Utils.toPrice(centAddPay)).append("\n");
			  ac = new TbAccounts();
			  ac.setLiving(nCur);
			  ac.setType(InComeItemType.JSFF.name());
			  ac.setCounts(addCount);
			  ac.setPrice(-centAddPay);
			  ac.setPrice2(centAddPay/iUnion);
			  ac.setName(sAddPayName);
			  ac.setEndstate("是");
			  ac.setEndtime(checkTime);
			  ac.setOpdate(DateUtil.toString(checkTime, "yyyy-MM-dd"));
			  ac.setOptime(new Date());
			  ac.setOpUser(Hotel.getCurrentUser().getName());
			  ac.setRemark(rUnion+"加收"+InComeUtil.getAutoLivingReMark(selectLive,false)+"共计:"+Utils.toPrice(centAddPay));
		}
		
		int allComsum =comsum+centAddPay;//总消费
		int pay=storage-allComsum;//应付
		int finalPay =0;//最终应付
		msg.append("总存额：").append(Utils.toPrice(storage)).append("\n");
		msg.append("已消费：").append(Utils.toPrice(allComsum)).append("\n");
		if(pay==0){
			msg.append("本次应付:").append("0").append("\n");
			finalPay=0;
		}else if(pay<0){
			msg.append("本次应付:").append(Utils.toPrice(-pay)).append("\n");
			finalPay=-pay;
		}else{
			msg.append("本次退返:").append(Utils.toPrice(pay)).append("\n");
			finalPay=pay;
		}
		//会员增加记录
		User user =Hotel.getCurrentUser();
		Memberchargehistrory mch =null;
		if(sPayMethod.equals(PayMethod.MEMBER_CARD.name()))
		{
			//TODO  
			if(storage!=0){
				UIUtils.alert("你在入住时已有预存:"+Utils.toPrice(storage)+"不能用会员卡结账!");
				return ;
			}
			String sCardNumber=mCardNumber.getValue();
			Member m =memberService.queryMemberOnCard(sCardNumber);
			if(m==null){
				UIUtils.alert("请用有效的会员卡结账!");
				return ;
			}
			int mExceed =memberService.exceedBalance(m,finalPay,false);
			int mBalance =memberService.queryMemberBalance(m);
			if(mExceed<0){
				  UIUtils.alert("当前会员余额不够！当前余额为："+Utils.toPrice(mBalance));
				  return ;
			}
		    mch =new Memberchargehistrory();
			mch.setMember(m);
			mch.setChargeTime(checkTime);
			mch.setPrice(-allComsum);
			mch.setChargetype("非自助");
			mch.setOptype(ChargeOpType.OnConsume.name());
			mch.setRemark(DateUtil.toString(checkTime, DateUtil.HOTEL_DEFAULT_FORMAT)+":"+rUnion+rMsg.toString());
			checkOutNo=m.getCardNo();
			
		}else if(sPayMethod.equals(PayMethod.CASH.name())){
			checkOutNo=orderNo;
			
		}else
		{
			finalAlert.append("当前是用").append(PayMethod.valueOf(sPayMethod).getDisplayName()).append("结账").append("\n");
			finalAlert.append("请结算人员"+user.getName()+"在结账完成后完成输入银行凭证单据号");
		}
		int invoice=Integer.valueOf((String)UIUtils.getSelectedValue(invoiceListbox));
		if(invoice==0){
			msg.append("未开票").append("\n");
		}else{
			msg.append("已开票").append("\n");
			finalAlert.append("请给客人开票").append("\n");
			}
		setCurLiving(nCur);
		TbCloseAccounts ca = new TbCloseAccounts();
		ca.setLiving(nCur);
		ca.setInvoice(invoice);
		ca.setTime(new Date());
		ca.setAccounts(allComsum);
		ca.setType(PayMethod.valueOf(sPayMethod).name());
		
		ca.setUsername(user.getName());
		ca.setUserId(user.getId());
		ca.setOrderNo(orderNo);
		ca.setSerialNumber(serialNumber);
		ca.setCheckOutNo(checkOutNo);
		ca.setNeedAccounts(InComeUtil.sysInComeDays(selectLive));
        if(UIUtils.confirm(msg.toString())){
        	incomeService.saveAllCheck(selectLive,ca,ac, mch,pay);
        	opTip.setValue("结账成功!");
        	if(finalAlert.length()>0)
        	  UIUtils.alert(finalAlert.toString());
        	okBtn.setDisabled(true);
        	success = true;
		}
	}
	public void memberCheckOut()
	{
		
	}

	public Date getEarlyTime() {
		return earlyTime;
	}
	public void setEarlyTime(Date earlyTime) {
		this.earlyTime = earlyTime;
	}
	public Date getCheckTime() {
		return checkTime;
	}
	public void setCheckTime(Date checkTime) {
		this.checkTime = checkTime;
	}

	public Living getCurLiving() {
		return curLiving;
	}

	public void setCurLiving(Living curLiving) {
		this.curLiving = curLiving;
	}

}
